package com.ys.service.hr.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.ys.constant.AppConstant;
import com.ys.dto.AddDto;
import com.ys.entity.base.TbBaseInfoArea;
import com.ys.entity.base.TbFileInfo;
import com.ys.entity.flow.YspModel;
import com.ys.entity.hr.ThrOperateRegistration;
import com.ys.entity.hr.ThrOperateRegistrationItem;
import com.ys.entity.hr.ThrUserArchives;
import com.ys.entity.sys.*;
import com.ys.enume.flow.FlowEnum;
import com.ys.enume.flow.YsProcInstEnum;
import com.ys.mapper.hr.HrMapper;
import com.ys.mapper.hr.ThrOperateRegistrationItemMapper;
import com.ys.mapper.hr.ThrOperateRegistrationMapper;
import com.ys.service.business.TbFileInfoService;
import com.ys.service.flow.YspTaskService;
import com.ys.service.hr.ThrOperateRegistrationService;
import com.ys.service.hr.ThrUserArchivesService;
import com.ys.service.sys.TsUserInfoService;
import com.ys.util.CheckUtil;
import com.ys.util.DateUtil;
import com.ys.util.RedisUtil;
import com.ys.util.dh.DhPassUtil;
import com.ys.util.shiro.ShiroUtils;
import com.ys.vo.Flow;
import com.ys.vo.R;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import java.text.SimpleDateFormat;
import java.time.LocalDateTime;
import java.time.temporal.ChronoUnit;
import java.util.*;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;

@Service("thrOperateRegistrationService")
public class ThrOperateRegistrationServiceImpl implements ThrOperateRegistrationService {
	private static final Logger logger = LoggerFactory.getLogger(ThrUserEntryApplyServiceImpl.class);

	@Autowired
	private ThrOperateRegistrationMapper thrOperateRegistrationMapper;

	@Autowired
	private ThrOperateRegistrationItemMapper thrOperateRegistrationItemMapper;

	@Autowired
	private YspTaskService yspTaskService;

	@Autowired
	private HrMapper hrMapper;

	@Autowired
	private CheckUtil checkUtil;

	@Autowired
	private TsUserInfoService tsUserInfoService;

	@Autowired
	private ThrUserArchivesService thrUserArchivesService;

	@Autowired
	private RedisUtil redisUtil;

	@Autowired
	private TbFileInfoService tbFileInfoService;


	/**
	 * 申请新增
	 * @param params
	 * @return
	 * @throws Exception
	 */
	@Override
	@Transactional(timeout=120,propagation= Propagation.REQUIRES_NEW)
	public R add(Map<String, Object> params, Long menuId) throws Exception {
		logger.info("申请新增传参:"+params);
		// 验证订单号
		if (new ThrOperateRegistration().setBid(params.get("bid").toString()).count() > 0) {
			return R.error("该申请单号已存在");
		}

		ThrOperateRegistration thrOperateRegistration = JSON.parseObject(JSON.toJSONString(params), ThrOperateRegistration.class);
		thrOperateRegistration.setStatus(1);//状态
		thrOperateRegistration.setEffectStock(0);//审批状态


		//获取制单人信息
		TsUserChange tsUserChange = new TsUserChange().setUserId(ShiroUtils.getUserId()).setOrderby("A.CreateTime DESC").queryFirst();
		if(tsUserChange!=null){
			thrOperateRegistration.setCreateChangeId(tsUserChange.getId());//制单人变更信息
		}else {
			R.error("未查询到制单人信息！");
		}

		//验证详情信息
		List<Map<String, Object>> paramsNewByItem = new ArrayList<>();
		if(params.get("subData")!=null){
			JSONArray subData = JSON.parseArray(params.get("subData").toString());
			for (int i = 0; i < subData.size(); i++) {
				JSONObject jSONObject = subData.getJSONObject(i);
				Map<String, Object> paramsNew = new HashMap<>();
				for (String key : jSONObject.keySet()) {
					paramsNew.put(key,jSONObject.get(key));
				}
				paramsNew.put("roleIdAttribute",1);//默认运营
				paramsNew.put("pbid",thrOperateRegistration.getBid());//单号
				paramsNewByItem.add(paramsNew);
			}
			String errorMsg = checkParamsByItem(paramsNewByItem, menuId);
			if(errorMsg!=null && !"".equals(errorMsg)){
				return R.error(errorMsg);
			}
		}else {
			return R.error("详情信息为空！");
		}
		//新增运营人员登记申请
		thrOperateRegistrationMapper.insert(thrOperateRegistration);
		YsRole ysRole = new YsRole().setName("运营人员").queryFirst();
		//新增运营人员登记详情
		for(Map<String, Object> item:paramsNewByItem){
			//获取用户UserId
			Map<String, Object> maxUserIdMap = hrMapper.getMaxUserId();
			String userIdStr = maxUserIdMap.get("maxUserId").toString();
			String userId = null;
			int userIdInt = Integer.parseInt(userIdStr);
			if(userIdInt==99999){
				userId = "000001";
			}else {
				userIdInt ++ ;
				//补0
				userId = String.format("%0"+5+"d", userIdInt);
			}
			ThrOperateRegistrationItem thrOperateRegistrationItem = JSON.parseObject(JSON.toJSONString(item), ThrOperateRegistrationItem.class);
			thrOperateRegistrationItem.setUserId(userId);
			thrOperateRegistrationItem.setStatus(1);
			if(ysRole!= null){
				thrOperateRegistrationItem.setRoleId(ysRole.getId());
			}
			thrOperateRegistrationItem.setPbid(thrOperateRegistration.getBid());
			thrOperateRegistrationItemMapper.insert(thrOperateRegistrationItem);
		}
		YsMenu ysMenu = new YsMenu().setId(menuId).queryFirst();
		if (ysMenu.getFlowModelId().longValue() != 0L) {
			YspModel yspModel = new YspModel().setId(ysMenu.getFlowModelId()).queryFirst();
			String codeModel = yspModel.getCode();
			String createUserId = ShiroUtils.getUserId();
			yspTaskService.init(codeModel, thrOperateRegistration.getBid(), createUserId);
		}
		return R.ok(AddDto.gotoEdit("/web/hr/thrOperateRegistration/toEdit?bid=" + thrOperateRegistration.getBid()));
	}


	/**
	 * 修改
	 */
	@Override
	public R update(Map<String, Object> params, Long menuId) throws Exception{
		logger.info("申请修改传参:"+params);

		ThrOperateRegistration thrOperateRegistration = JSON.parseObject(JSON.toJSONString(params), ThrOperateRegistration.class);
		// 验证状态
		YsProcInst ysProcInst = new YsProcInst().setBid(thrOperateRegistration.getBid()).queryFirst();
		if (ysProcInst == null) {
			return R.error("审批数据不存在，无法编辑");
		} else if (ysProcInst.getStateFlow() != YsProcInstEnum.StateFlow.INIT.value) {
			return R.error("已流转，无法编辑");
		}

		//验证详情信息
		List<Map<String, Object>> paramsNewByItem = new ArrayList<>();
		if(params.get("subData")!=null){
			JSONArray subData = JSON.parseArray(params.get("subData").toString());
			for (int i = 0; i < subData.size(); i++) {
				JSONObject jSONObject = subData.getJSONObject(i);
				Map<String, Object> paramsNew = new HashMap<>();
				for (String key : jSONObject.keySet()) {
					paramsNew.put(key,jSONObject.get(key));
				}
				paramsNew.put("roleIdAttribute",1);//默认运营
				paramsNew.put("pbid",thrOperateRegistration.getBid());//单号
				paramsNewByItem.add(paramsNew);
			}
			String errorMsg = checkParamsByItem(paramsNewByItem, menuId);
			if(errorMsg!=null && !"".equals(errorMsg)){
				return R.error(errorMsg);
			}
		}else {
			return R.error("详情信息为空！");
		}
		//新增、修改运营人员登记详情
		for(Map<String, Object> item:paramsNewByItem){
			ThrOperateRegistrationItem thrOperateRegistrationItem = JSON.parseObject(JSON.toJSONString(item), ThrOperateRegistrationItem.class);
			if(thrOperateRegistrationItem.getId()!=null && !"".equals(thrOperateRegistrationItem.getId())){
				//修改
				thrOperateRegistrationItemMapper.update(thrOperateRegistrationItem);
			}else {//新增
				//获取用户UserId
				Map<String, Object> maxUserIdMap = hrMapper.getMaxUserId();
				String userIdStr = maxUserIdMap.get("maxUserId").toString();
				String userId = null;
				int userIdInt = Integer.parseInt(userIdStr);
				if(userIdInt==99999){
					userId = "000001";
				}else {
					userIdInt ++ ;
					//补0
					userId = String.format("%0"+5+"d", userIdInt);
				}
				thrOperateRegistrationItem.setUserId(userId);
				thrOperateRegistrationItem.setPbid(thrOperateRegistration.getBid());
				thrOperateRegistrationItem.setStatus(1);
				thrOperateRegistrationItemMapper.insert(thrOperateRegistrationItem);
			}
		}


		return R.ok(AddDto.noAction());
	}



	//删除
	@Override
	@Transactional
	public R delete(Long id) throws Exception{
		if (id == null) {
			return R.error("ID不能为空");
		}
		ThrOperateRegistration entity = new ThrOperateRegistration().setId(id).queryFirst();
		if (entity.getEffectStock() == FlowEnum.EffectStock.EFFECTED.value) {
			return R.error("已生效数据无法删除");
		}
		// 验证是否制单人
		String loginUserId = ShiroUtils.getUserId();
		TsUserChange tsUserChange = new TsUserChange().setId(entity.getCreateChangeId()).queryFirst();
		if (!tsUserChange.getUserId().equals(loginUserId) && !"admin".equals(loginUserId)) {
			return R.error("非制单人，无法删除");
		}
		//删除
		thrOperateRegistrationMapper.deleteTrue(id);
		//删除列表信息
		hrMapper.deleteOperateRegistrationItemByPbid(entity.getBid());
		//删除流程
		yspTaskService.flowDelete(entity.getBid(), loginUserId);
		return R.ok();
	}


	/**
	 * 流转通过
	 */
	@Override
	@Transactional
	public R flowPass(Long id, String loginUserId) throws Exception {

		ThrOperateRegistration entity = new ThrOperateRegistration().setId(id).queryFirst();
		Flow f = yspTaskService.flowPass(entity.getBid(), loginUserId);
		if (f.getCode() == Flow.Code.FAILED.value) {
			return R.error(f.getMsg());
		} else {
			if (f.getState() == Flow.State.FINISH.value) {
				flowFinish(entity.getBid());
			}
			return R.ok();
		}
	}

	/**
	 * 流转结束
	 */
	@Override
	@Transactional
	public void flowFinish(String bid) throws Exception {

		ThrOperateRegistration thrOperateRegistration = new ThrOperateRegistration().setBid(bid).queryFirst();
		YsProcInst ysProcInst = new YsProcInst().setBid(thrOperateRegistration.getBid()).queryFirst();
		if (ysProcInst.getStateFlow() != YsProcInstEnum.StateFlow.FINISH.value) {
			return;
		}
		Date theDate = new Date();
		thrOperateRegistration.setEffectStock(FlowEnum.EffectStock.EFFECTED.value);
		thrOperateRegistration.setUpdateTime(theDate);

		//时间格式
		SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd");

		List<ThrOperateRegistrationItem> entityItem = new ThrOperateRegistrationItem()
				.setPbid(bid)
				.queryList();

		if(entityItem!=null && entityItem.size()>0){
			for(ThrOperateRegistrationItem item: entityItem){
				//获取用户对应的组织信息
				TsOrganizationInfo tsOrganizationInfo = new TsOrganizationInfo().setOrgid(item.getDeptId()).queryFirst();
				//获取用户对应的角色（岗位）信息
				YsRole ysRole = new YsRole().setName("运营人员").queryFirst();
				//根据行政编码获取城市名称
				TbBaseInfoArea tbBaseInfoAreaByCity = null;
				if(item.getAdcode()!=null){
					tbBaseInfoAreaByCity = new TbBaseInfoArea().setCode(item.getAdcode()).queryFirst();
				}
				//默认密码
				String passWord = "123456";

				//*************************更新员工信息表*************************
				Map<String, Object> paramsByUserInfo = new HashMap<>();
				paramsByUserInfo.put("userId",item.getUserId());//用户工号
				paramsByUserInfo.put("userName",item.getUserName());//用户名字
				//获取加密密码
				String passEncrypt = DhPassUtil.encryptPassword(item.getUserId(), passWord, AppConstant.PASSWORD_SALT);
				paramsByUserInfo.put("userPassWord",passEncrypt);//密码
				paramsByUserInfo.put("userPassWord2",passEncrypt);//密码
				paramsByUserInfo.put("userState","在职");//在职、离职状态
				paramsByUserInfo.put("userSex",(item.getUserSex()==0?"女":"男"));//性别
				Date date = formatter.parse(item.getBirthday());//时间类型转换
				paramsByUserInfo.put("userBirthday",date);//生日
				//paramsByUserInfo.put("userCity",tbBaseInfoAreaByJg!=null?tbBaseInfoAreaByJg.getName():null);//城市名称
				//paramsByUserInfo.put("userAddress",entity.getAddress());//详细地址
				paramsByUserInfo.put("userPhone1",item.getTelephone());//电话1
				paramsByUserInfo.put("userLeader",item.getHeadUserId());//上级用户工号
				paramsByUserInfo.put("organizationid",tsOrganizationInfo!=null?tsOrganizationInfo.getGuid():null);//组织Id
				paramsByUserInfo.put("disabled",0);//在职状态(在职0、离职1)离职1)
				paramsByUserInfo.put("cid",tsOrganizationInfo!=null?tsOrganizationInfo.getCid():null);//公司
				paramsByUserInfo.put("cidName",tsOrganizationInfo!=null?tsOrganizationInfo.getCidName():null);//公司名称
				paramsByUserInfo.put("orgId",tsOrganizationInfo!=null?tsOrganizationInfo.getId():null);//所属组织机构ID
				paramsByUserInfo.put("deptId",item.getDeptId());//部门Id
				paramsByUserInfo.put("deptName",tsOrganizationInfo!=null?tsOrganizationInfo.getDeptName():null);//部门名字
				paramsByUserInfo.put("deptPath",tsOrganizationInfo!=null?tsOrganizationInfo.getDeptPath():null);//部门Id路径
				paramsByUserInfo.put("deptPathName",tsOrganizationInfo!=null?tsOrganizationInfo.getDeptPathName():null);//部门名字路径
				paramsByUserInfo.put("userType",(item.getRoleIdAttribute()==0?"职能":"运营"));//岗位属性(0职能、1运营)
				paramsByUserInfo.put("vBgs",tbBaseInfoAreaByCity.getName());//工作地址
				paramsByUserInfo.put("roleId",ysRole!=null?ysRole.getId():null);//角色Id
				//paramsByUserInfo.put("positionGuid",ysRole.);//报销奖励状态，0未奖励1已奖励
				paramsByUserInfo.put("roleName",ysRole!=null?ysRole.getName():null);//角色名称
				paramsByUserInfo.put("stateReimburseReward","0");//报销奖励状态，0未奖励1已奖励
				paramsByUserInfo.put("status","1");
				paramsByUserInfo.put("sourceType",2);//用户来源（1直接新增，2运营人新增，3职能入职）
				// 同步1.0岗位
				TsRoleInfo tsRoleInfo = new TsRoleInfo().setRoleName(ysRole.getName()).queryFirst();
				paramsByUserInfo.put("positionGuid",tsRoleInfo.getGuid());

				R isAddUserInfo = tsUserInfoService.addByNew(paramsByUserInfo);
				if(isAddUserInfo.getCode()==1){//失败
					//return R.error(R.getMsg());
					return;
				}
				//*************************更新员工档案信息*************************
				Map<String, Object> paramsByUserArchives = new HashMap<>();
				int num = 0;
				//设置档案编码（格式：YGDA年月日三位序号）
				if(redisUtil.get("thrUserArchivesBid")!= null && !"".equals(redisUtil.get("ThrUserArchivesBid"))){
					num = Integer.parseInt(redisUtil.get("thrUserArchivesBid"))+1;
				}
				redisUtil.set("thrUserArchivesBid",num+"");//加一更新
				LocalDateTime midnight = LocalDateTime.now().plusDays(1).withHour(0).withMinute(0).withSecond(0).withNano(0);
				long seconds = ChronoUnit.SECONDS.between(LocalDateTime.now(), midnight);
				redisUtil.setEx("thrUserArchivesBid",num+"",seconds, TimeUnit.SECONDS);//设置过期时间
				//设置档案编码（格式：YGDA年月日三位序号）
				String archivesBid = "YGDA"+ DateUtil.getYYYYMMDD(theDate)+String.format("%0"+3+"d", num);
				//入参
				paramsByUserArchives.put("archivesBid",archivesBid);//档案编码（格式：YGDA年月日三位序号）
				paramsByUserArchives.put("userId",item.getUserId());//用户工号
				paramsByUserArchives.put("userName",item.getUserName());//用户名字
				paramsByUserArchives.put("userSex",item.getUserSex());//性别
				paramsByUserArchives.put("birthday",item.getBirthday());//生日
				paramsByUserArchives.put("education",item.getEducation());//学历
				//paramsByUserArchives.put("graduationDate",item.getGraduationDate());//毕业日期(YYYY-MM-DD)
				//paramsByUserArchives.put("graduationSchool",entity.getGraduationSchool());//毕业学校
				//paramsByUserArchives.put("major",item.getMajor());//主修专业
				paramsByUserArchives.put("telephone",item.getTelephone());//联系电话
				//paramsByUserArchives.put("address",entity.getAddress());//居住地址
				paramsByUserArchives.put("workCity",item.getAdcode());//工作城市
				paramsByUserArchives.put("roleId",item.getRoleId());//岗位
				paramsByUserArchives.put("roleIdAttribute",item.getRoleIdAttribute());//岗位属性
				paramsByUserArchives.put("deptId",item.getDeptId());//部门
				paramsByUserArchives.put("headUserId",item.getHeadUserId());//上级用户工号
				//paramsByUserArchives.put("belongCompany",item.getBelongCompany());//所属公司
				//paramsByUserArchives.put("graduationCertificate",entity.getGraduationCertificate());//毕业证书附件路径
				//paramsByUserArchives.put("educationCertificate",entity.getEducationCertificate());//学历证书附件路径
				//paramsByUserArchives.put("laborContract",entity.getLaborContract());//劳动合同附件路径
				paramsByUserArchives.put("otherFile",item.getOtherFile());//其他附件路径
				paramsByUserArchives.put("remark",item.getWork()+","+item.getRemark());//备注
				paramsByUserArchives.put("userState",2);//员工状态（0实习、1试用、2正式、3离职）
				paramsByUserArchives.put("officeId",item.getOfficeId());//办公室名称
				ThrUserArchives thrUserArchives = thrUserArchivesService.add(paramsByUserArchives);
				long archivesId = thrUserArchives.getId();

				//同步附件信息
				List<TbFileInfo> tbFileInfoList = new TbFileInfo().setSourceId(item.getId()).setSourceCode("otherFile").setSourceType(7).queryList();
				if(tbFileInfoList!=null && tbFileInfoList.size()>0){
					//其他附件
					List<TbFileInfo> tbFileInfoByOtherFile = tbFileInfoList.stream().filter(fileItem->fileItem.getSourceCode().equals("otherFile")).collect(Collectors.toList());
					if(tbFileInfoByOtherFile.size()>0){
						for(TbFileInfo fileItem:tbFileInfoByOtherFile){
							fileItem.setSourceId(archivesId);
							fileItem.setSourceType(6);
							tbFileInfoService.add(fileItem);
						}
					}
				}
			}
		}

		//修改主表信息
		thrOperateRegistrationMapper.update(thrOperateRegistration);


	}


	/**
	 * 详情信息 参数验证
	 */
	public String checkParamsByItem(List<Map<String, Object>> subData, Long menuId) throws Exception {
		String backMsg = "";
		if(subData==null || subData.size()<=0){
			return "详情信息参数为空！";
		}
		//获取pc字段数据
		List<YsCol> listField = new YsCol()
				.where("A.MenuId = "+menuId)
				.setOrderby("A.SortNo ASC")
				.queryList();
		for (int i = 0; i < subData.size(); i++) {
			Map<String, Object> msg = subData.get(i);
			if(msg==null){
				backMsg = "详情信息第"+(i+1)+"行的参数为空！";
				continue;
			}
			//验证必填字段的非空；其他字段的长度限制、类型
			backMsg = checkUtil.checkTableColLengthAndDataType("TP_AmazonRegionItem",listField,msg,ysColItem->ysColItem.getFormEditRequired()!=null && ysColItem.getFormEditRequired() == 1);
			if(msg.get("telephone")!=null && !checkUtil.isPhone(msg.get("telephone").toString())){
				backMsg = "详情信息第"+(i+1)+"行的手机号格式有误！";
			}
		}
		return backMsg;
	}

	//获取子列表数据
	@Override
	@Transactional
	public List<Map<String, Object>> getItemList( String bid) throws Exception{

		List<Map<String, Object>> itemList = new ThrOperateRegistrationItem()
				.addField("FORMAT(P.UpdateTime, 'yyyy-MM-dd hh:mm:ss') AS auditingTime")
				//.addField("'运营' AS roleIdAttribute")
				.addField("A.HeadUserId + '/' + U.UserName AS headUserName")
				.addField("O.DeptName AS deptName")
				.addField("R.Name AS roleName")
				.addField("BA1.HigherLevelPath + ',' + BA1.Name AS workCityName")
				.addField("AA.VId AS officeName")//所属办公室地址


				.addLeftJoin("YS_ProcInst P ON P.Bid = A.Pbid ")
				.addLeftJoin("TS_OrganizationInfo O ON O.Orgid = A.DeptId AND 1=1")
				.addLeftJoin("TS_UserInfo U ON U.UserId = A.HeadUserId AND 1=1")
				.addLeftJoin("YS_Role R ON R.Id = A.RoleId AND 1=1")
				.addLeftJoin("TB_BaseInfoArea BA1 ON BA1.Code = A.Adcode AND 1=1")
				.addLeftJoin("TB_BaseInfo AA ON AA.Id = A.OfficeId AND 1=1")
				.setPbid(bid)
				.queryMap();
		return itemList;
	}

}
